package com.tau.egonetwork.profiles;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;

import com.tau.egonetwork.common.Configurations;
import com.tau.egonetwork.common.Log;
import com.tau.egonetwork.exceptions.EgoNetworkException;

public class ProfileFile {
	
	private final static String EXTENSION = ".prf";
	
	public static enum SocialNetworks {
		Facebook("fb"),
		Linkedin("in");
		
		private final String val;
		private SocialNetworks(String value) {
			this.val = value;
		}

		@Override
		public String toString() {
			return val;
		}
	}
	
	public static void saveToFile(SocialNetworks net, MainProfile<?> profile) {

		//if DIR doesn't exist, create it:
		File dir = new File(Configurations.profilesDirectory());
		if (!dir.exists()) {
			dir.mkdir();
		}
		
		ObjectOutputStream oos = null;

		String filename = generateFileName(net, profile);
		File file = new File(filename);

		try {
			//create file if doesn't exist:
			if (!file.exists()) {
				file.createNewFile();
			}
			
			//open file for writing (mark append=false to override existing file):
			FileOutputStream fout = new FileOutputStream(file, false);
			oos = new ObjectOutputStream(fout);
			oos.writeObject(profile);
			
		} catch (FileNotFoundException e) {
			//this should not happen!! we had just checked that the file exists and created it if not!!
			throw new EgoNetworkException("Unexpected error: no file found for this Profile.", e);
		} catch (IOException e) {
			Log.writeExceptionToLog(e);
			throw new EgoNetworkException("Unable to write Profile.", e);
		} finally {
			try {
				if (oos != null)
					oos.close();
			} catch (IOException e) {
				Log.writeExceptionToLog(e);
			}
		}
		
	}
	
	public static MainProfile<?> openFile(MainProfile<?> profile, SocialNetworks network) {
		return openFile(generateFileName(network, profile));
	}
	
	public static MainProfile<?> openFile(String path) {
		
		//calculate path:
		path = Configurations.profilesDirectory() + File.separator + path;
		
		//read file and create object, or return null if exception thrown:
		InputStream file = null;
		try {
			file = new FileInputStream(path);
			InputStream buffer = new BufferedInputStream(file);
			ObjectInput input = new ObjectInputStream(buffer);
			return (MainProfile<?>)input.readObject();
		} catch (FileNotFoundException e) {
			throw new EgoNetworkException("Unexpected error: no file found for this Profile.", e);
		} catch (IOException e) {
			Log.writeExceptionToLog(e);
			throw new EgoNetworkException("Unable to read Profile.", e);
		} catch (ClassNotFoundException e) {
			Log.writeExceptionToLog(e);
			throw new EgoNetworkException("Unable to read Profile.", e);
		} finally {
			if (file != null)
				try {
					file.close();
				} catch (IOException e) {
					Log.writeExceptionToLog(e);
				}
		}	
	}
	
	private static String generateFileName(SocialNetworks net, MainProfile<?> profile) {
		return Configurations.profilesDirectory() + File.separator + net + "_" + profile.getID()
				+ "_" + profile.getName() + EXTENSION;
				
	}
	
	public static String getProfileNameFromFileName(String filename, SocialNetworks type) {
		
		String profileName = filename.replace(EXTENSION, "");
		if (type != null) {
			profileName = profileName.replace(type + "_", "");
		}
		int indx = profileName.lastIndexOf("_");
		if (indx < 0)
			return profileName; //<<-- should not happen, this is wrong and would later throw a FileNotFoundException
		
		return profileName.substring(indx + 1);

	}
	
	public static String getProfileIDFromFileName(String filename, SocialNetworks type) {
		
		String profileID = filename.replace(EXTENSION, "");
		if (type != null) {
			profileID = profileID.replace(type + "_", "");
		}
		int indx = profileID.lastIndexOf("_");
		if (indx < 0)
			return profileID; //<<-- should not happen, this is wrong and would later throw a FileNotFoundException
		
		return profileID.substring(0, indx);

	}
	
	public static SocialNetworks getSocialNetworkOfFile(String filename) {
		
		int end = filename.indexOf("_");	
		if (end < 0)
			return null;
		
		String network = filename.substring(0, end);
		if (network.equals(SocialNetworks.Facebook.toString()))
			return SocialNetworks.Facebook;
		
		if (network.equals(SocialNetworks.Linkedin.toString()))
			return SocialNetworks.Linkedin;
		
		return null;
	}
	
	public static HashMap<String, String> getAllProfileFiles(final SocialNetworks type) {
		
		File directory = new File(Configurations.profilesDirectory());
		if (!directory.exists())
			return null;
		
		File[] files = directory.listFiles(new FilenameFilter() {
			
			@Override
			public boolean accept(File dir, String name) {
				if (type != null) {
					return name.endsWith(EXTENSION) && name.startsWith(type + "_");
				}
				return name.endsWith(EXTENSION);
			}
		});
		
		if (files == null)
			return null;
		
		HashMap<String, String> results = new HashMap<String, String>();
		
		for (File file : files) {
			
			String profileName = getProfileNameFromFileName(file.getName(), type);
			results.put(file.getName(), profileName);
			
		}
		
		return results;
	}
	
}
